from serverproxy import *
from mainwindow import *
from textualanalysisframe import *
from classesframe import *
from projectframe import *
from projectmembersframe import *
from classformframe import *
from projectlistdialog import *
from scrumsframe import *
from newscrumdialog import *
import tkMessageBox

class Controller(object):
    """
    Handles the communication between the UI and the server.
    """
    
    def __init__(self):
        self.serverProxy = ServerProxy("http://localhost", 0xBEEF)
        self.window = MainWindow(self)
        self.project = None
        
    def run(self):
        self.window.mainloop()
        
    def updateWindowTitle(self):
        if self.project == None:
            self.window.title("DBMS")
        else:
            self.window.title(self.project.name + " - DBMS")
        
        
        
        
    """ ------------ MainWindow Event Handlers ------------ """
        
        
        

    def onCreateProject(self):
        """
        Invoked when the create project menu entry is clicked
        """
        name = askstring('Nouveau projet', 'Veuillez entrer le nom du nouveau projet')
        if name == None:
            return
        
        project = self.serverProxy.createProject(name)
        if project == None:
            tkMessageBox.showerror("Erreur", "Impossible de creer le projet")
            return
        
        self.project = project
        self.updateWindowTitle()
        self.window.destroyFrame()
        
    def onOpenProject(self):
        """
        Invoked when the open project menu entry is clicked
        """
        projects = self.serverProxy.getProjects()
        if projects == None or len(projects) == 0:
            tkMessageBox.showerror("Erreur", "Aucun projet n'existe")
            return
            
        self.dialog = ProjectListDialog(self.window, self)
        for project in projects:
            self.dialog.addProjectName(project.name)
        self.dialog.mainloop()

    def onCancelProjectOpening(self):
        """
        Invoked when the cancel button on the open project dialog is clicked
        """
        self.dialog.destroy()
        
    def onOpenSpecificProject(self):
        """
        Invoked when the open button on the open project dialog is clicked.
        """
        name = self.dialog.getSelectedProjectName()
        project = self.serverProxy.getProjectByName(name)
        if project == None:
            tkMessageBox.showerror("Erreur", "Impossible d'ouvrir le projet")
            return
        
        self.project = project
        self.dialog.destroy()
        self.updateWindowTitle()
        self.window.destroyFrame()
        
        
        
        
        
    """ ------------ ProjectFrame-related ------------ """
    
    
    
    
    def onShowProject(self):
        """
        Invoked when the project view is selected in the window
        """
        if self.project == None:
            tkMessageBox.showerror("Erreur", "Aucun projet n'est charge")
            return 
        
        if self.window.frame.__class__ == ProjectFrame:
            return
        
        self.window.destroyFrame()
        frame = ProjectFrame(self.window, self)
        frame.setName(self.project.name)
        frame.setSummary(self.project.summary)
        frame.setMandate(self.project.mandate)
        self.window.setFrame(frame)
    
    def onSaveProjectChanges(self, name, summary, mandate):
        self.serverProxy.updateProject(self.project.id, name, summary, mandate)
        self.project.name = name
        self.project.summary = summary
        self.project.mandate = mandate
        
   
        
    """ ------------ Project CRC related ------------ """
        
        
    def onShowCrc(self):
        if self.project == None:
            tkMessageBox.showerror("Erreur", "Aucun projet n'est charge")
            return 
        
        #if self.window.frame.__class__ == ClassesFrame:
        #    return
        
        self.window.destroyFrame()
        frame = ClassesFrame(self.window, self)
        classes = self.serverProxy.getProjectClasses(self.project.id)
        for crc in classes:
            frame.setClassesListbox(crc.name)
        self.window.setFrame(frame)  
   
    def onMakeClassForm(self, className): 
        classes = self.serverProxy.getProjectClasses(self.project.id)
        self.window.classFormWindowObj = None
        for crc in classes:
            if crc.name == className:
                self.window.classFormWindowObj = ClassFormWindow(self.window, crc)
        if self.window.classFormWindowObj == None:
            self.window.classFormWindowObj = ClassFormWindow(self.window, None)
        
    def onConfirmClassCreation(self, name, responsabilities, collaborations, classId, mode):
        if name == None or responsabilities == [] or collaborations == []:
           tkMessageBox.showerror("Erreur", "tous les champs doivent contenir au moins un element")
        else:
            if mode == "create":
                canAdd = True
                for clazz in self.serverProxy.getProjectClasses(self.project.id):
                    if clazz.name == name:
                        canAdd = False
                if canAdd:
                    self.serverProxy.createClass(self.project.id, name, responsabilities, collaborations)
                    self.window.classFormWindowObj.destroy()
                else:
                    tkMessageBox.showerror("Erreur", "Vous ne pouvez pas creer une classe avec un nom deja existant")        
            else:
                self.serverProxy.updateClass(self.project.id, name, responsabilities, collaborations, classId)
                self.window.classFormWindowObj.destroy()
        self.onShowCrc()
                
    def onQuitClassFormWindow(self):
        self.window.classFormWindowObj.destroy()
    
    def onEditListboxRequest(self, content = None):  
        return askstring('Modifier le champ', 'Veuillez entrer la nouvelle description', initialvalue=content, parent=self.window.classFormWindowObj)  
        
        
        
        
        
    """ ------------ Textual Analysis related ------------ """
    
    
    
    def onShowTextualAnalysis(self):
        """
        Invoked when the textual analysis view is selected in the window
        """
        if self.project == None:
            tkMessageBox.showerror("Erreur", "Aucun projet n'est charge")
            return 
        
        if self.window.frame.__class__ == TextualAnalysisFrame:
            return
        
        self.window.destroyFrame()
        
        frame = TextualAnalysisFrame(self.window, self)
        frame.setMandate(self.project.mandate)
        
        keyExpressions = self.serverProxy.getProjectKeyExpressions(self.project.id)
        frame.setKeyExpressions(keyExpressions)
        
        self.window.setFrame(frame)
        
    def onSaveTextualAnalysisChanges(self):
        self.serverProxy.clearProjectKeyExpressions(self.project.id)
        
        for keyExpression in self.window.frame.getKeyExpressions():
            self.serverProxy.addProjectKeyExpression(self.project.id,
                keyExpression.expression, keyExpression.type, keyExpression.isExplicit)
        
        
        
    """ ------------ Project Members related ------------ """
        
        
        
    def onShowProjectMembers(self):
        """
        Invoked when the project members view is selected in the window
        """
        if self.project == None:
            tkMessageBox.showerror("Erreur", "Aucun projet n'est charge")
            return 
        
        if self.window.frame.__class__ == ProjectMembersFrame:
            return
        
        self.window.destroyFrame()
        
        self.frame = ProjectMembersFrame(self.window,self)
        
        people = self.serverProxy.getProjectMembers(self.project.id)
        if people:
            for person in people:
                self.frame.allMembers.insert(END,str(person.firstName)+" "+str(person.lastName)+"\n")
        
        self.window.setFrame(self.frame)
    
    def saveMembers(self, memberNamesString):
        memberNames = memberNamesString.split("\n")
        for memberName in memberNames:
            if memberName.strip() == "":
                continue
            
            memberNameParts = memberName.split(" ")
            if len(memberNameParts) < 2:
                continue
            
            memberFirstName = memberNameParts[0]
            memberLastName = memberNameParts[1]
            person = self.serverProxy.createPerson(memberFirstName, memberLastName)
            self.serverProxy.addProjectMember(self.project.id, person.id)
            
            
                        
            
    """--------------- Scrums related ---------------------"""
    
    
    def onShowScrums(self):
        if self.project == None:
            tkMessageBox.showerror("Erreur", "Aucun projet n'est charge")
            return
        
        if self.window.frame.__class__ == ProjectMembersFrame:
            return
        
        scrums = self.serverProxy.getProjectScrums(self.project.id)
        
        dates = []
        for scrum in scrums:
            if scrum.date not in dates:
                dates.append(scrum.date)

        members = self.serverProxy.getProjectMembers(self.project.id)
            
        self.window.destroyFrame()
        self.frame = ScrumsFrame(self.window, self)
        for date in dates:
            self.frame.addDate(date)
        for member in members:
            self.frame.addProjectMemberName(member.name)
        self.window.setFrame(self.frame)
        
    def onShowSelectedScrum(self):
        date = self.frame.getSelectedDate()
        memberName = self.frame.getSelectedProjectMemberName()
        
        members = self.serverProxy.getProjectMembers(self.project.id)
        
        memberID = None
        for member in members:
            if member.name == memberName:
                memberID = member.id
                break
        
        if memberID == None:
            return
        
        scrum = self.serverProxy.getScrum(self.project.id, date, memberID)
        
        if scrum == None:
            self.frame.setAccomplished("")
            self.frame.setProblems("")
            self.frame.setMission("")
            return
        
        self.frame.setAccomplished(scrum.accomplished)
        self.frame.setProblems(scrum.problems)
        self.frame.setMission(scrum.mission)
        
    def onAddScrum(self):
        members = self.serverProxy.getProjectMembers(self.project.id)
        
        self.dialog = NewScrumDialog(self.window, self)
        for member in members:
            self.dialog.addProjectMemberName(member.name)
        self.dialog.mainloop()
        
    def onNewScrumSaved(self):
        members = self.serverProxy.getProjectMembers(self.project.id)
        memberName = self.dialog.getSelectedProjectMemberName()
        
        for person in members:
            if person.name == memberName:
                self.serverProxy.addScrum(self.project.id, person.id,
                    self.dialog.getAccomplished(),
                    self.dialog.getProblems(),
                    self.dialog.getMission())
                break
        
        self.dialog.destroy()
        
        

if __name__ == '__main__':
    controller = Controller()
    controller.run()